package Er

import (
	"database/sql"
	"db2s/global"
	"reflect"
	"sync"
)

var mutex sync.Mutex

func reflectMap(value, n any) {
	global.MapStructValues(reflect.ValueOf(value), reflect.ValueOf(n).Elem())
}
func oracleRef(s, d any) any {
	reflectMap(s, d)
	return d
}
func mysqlRef(s, d any) any {
	reflectMap(s, d)
	return d
}
func clusterRef(s, d any) any {
	reflectMap(s, d)
	return d
}
func sqlserverRef(s, d any) any {
	reflectMap(s, d)
	return d
}
func dmRef(s, d any) any {
	reflectMap(s, d)
	return d
}

var (
	dbTypeInterFuncRef = map[string]reflect.Value{
		"cluster":   reflect.ValueOf(clusterRef),
		"mysql":     reflect.ValueOf(mysqlRef),
		"oracle":    reflect.ValueOf(oracleRef),
		"sqlserver": reflect.ValueOf(sqlserverRef),
		"dm":        reflect.ValueOf(dmRef),
	}
)

type TableConnEr interface {
	Open(s global.Conn) (result global.ConnPool, err error)
	Close(db map[string]*sql.DB)
}

type TableSumEr interface {
	Rows(s global.TableSumInput) (rowsCount global.RowsReturnResult, err error)
	Count(s global.TableSumInput) (rowsCount global.CountReturnResult, err error)
	CountDirect(s global.TableSumInput) (bool, int64) //根据实例判断count的方式
}
type LengthLimitEr interface {
	MetaLengthLimit(s global.LengthLimitInput) (length int64, err error)
	SchemaName(s global.LengthLimitInput)
	TableName()
	TableComment()
	ColumnName()
	ColumnComment()
	IndexName()
	Index()
}
type TableSqlEr interface {
	SelectColumn(s global.SelectColumnInput) (c, d []string, err error)
	WhereGenerate(s global.WhereGenerateInput) (ConditionSlice []string, err error)
	OrderBY(s global.WhereGenerateInput) (orderByColumn string, err error)
	Prefix(s global.PrefixInput) (string, error)
	Insert(s global.PrefixInput) (any, error)
	Delete(s global.PrefixInput) (any, error)
}
type TableColumnEr interface {
	GetColumnType(s global.GetColumnTypeInput) (any, error)
	All(s global.GetColumnTypeInput) (result global.AllReturnResult, err error)
	DropColumnSql(s global.GetColumnTypeInput) (any, error)
	AddColumnSql(s global.GetColumnTypeInput) (any, error)
	ModifyColumnSql(s global.GetColumnTypeInput) (any, error)
	CreateSql(s global.GetColumnTypeInput) (result global.CreatSqlResult, err error)
}

type IndexEr interface {
	IndexColumn(s global.TablesMetaInfoInput) (any, error)
	IndexChoice(s global.TablesMetaInfoInput) (any, error)
	IndexMerge(s global.TablesMetaInfoInput) global.IndexMerge
	IndexOptimizerTrace(s global.TablesMetaInfoInput) (any, error)
	DropIndexSql(s global.TablesMetaInfoInput) (any, error)
	AddIndexSql(s global.TablesMetaInfoInput) (any, error)
	ModifyIndexSql(s global.TablesMetaInfoInput) (any, error)
}
type PartitionEr interface {
	IfTablePartitionSum(s global.TablesMetaInfoInput) (res global.PartitionSumReturnResult, err error)
	FirstSubPartNameMarge(s global.TablesMetaInfoInput) (any, error)
	PartitionConfig(s global.TablesMetaInfoInput) (any, error)
	GetPartMeta(s global.TablesMetaInfoInput) (res global.PartMetaResultS, err error)
	DropPartitionSql(s global.TablesMetaInfoInput) (any, error)
	AddPartitionSql(s global.TablesMetaInfoInput) (any, error)
	ModifyPartitionSql(s global.TablesMetaInfoInput) (any, error)
}

type MetaExistEr interface {
	JobExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	ViewExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	SeqExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	CustomizeTypeExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	TriggerExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	ForeignExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	FuncExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	ProcedureExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	PackageExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	TableExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
	DataBaseExist(s global.TablesMetaInfoInput) (res global.ObjectExistReturnResult, err error)
}
type MetaNameExistEr interface {
	TableName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
	JobName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
	ViewName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
	SeqName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
	CustomizeTypeName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
	TriggerName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
	ForeignName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
	FuncName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
	ProcedureName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
	PackageName(s global.TablesMetaInfoInput) (returnResult global.ObjectNameReturnResult, err error)
}

// TablesMetaInfoEr 表粒度的统计信息
type TablesMetaInfoEr interface {
	AvgRowLength(s global.TablesMetaInfoInput) (res global.AvgRowLengthReturnResult, err error)
	DataSize(s global.TablesMetaInfoInput) (result global.DataSizeReturnResult, err error)
	Comment(s global.TablesMetaInfoInput) (result global.TableCommentReturnResult, err error)
	IfTableLob(s global.TablesMetaInfoInput) (result global.TableBigVarcharMeta, err error)
	IfBigVarchar(s global.TablesMetaInfoInput) (result global.TableBigVarcharMeta, err error)
	MetaNameExistEr
	MetaExistEr
	PartitionEr
	IndexEr
}
type TableMetaEr interface {
}

type IndexDataEr interface {
	StartPart(s global.StartPart) (result any, err error)
}
type RowsDataEr interface {
	Sql(s global.StartPart) (string, error)
	Data(s global.RowsDataInput) (global.ExecSqlResult, error)
	MissData(s global.RowsDataInput) (result global.ExecSqlResult, err error)
	//CrC32Sql(s global.StartPart) (string, error)
	//Md5Sql(s global.StartPart) (string, error)
}
type InstanceEr interface {
	Position(s global.Position) (any, error)
}
type SchemaObjectEr interface {
	Job(input global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
	View(input global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
	Seq(s global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
	Trigger(s global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
	Func(s global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
	Procedure(s global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
	Foreign(s global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
	Package(s global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
	Type(s global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
	Create(s global.SchemaObjectInput) (res global.SchemaObjectReturnResult, err error)
}
type RowsActiveEr interface {
	Insert(s global.RowsActiveInput) (any, error)
	Delete(s global.RowsActiveInput) (any, error)
	//Update()
}
type MetaEr interface {
}
type TableActiveEr interface {
	Truncate(s global.TableActiveInput) error
	//DataLocks(s global.TableActiveInput) (any,error)
	Analyze(s global.TableActiveInput) (any, error)
	OptimizerOrderBy(s global.TableActiveInput) (any, error) //同一组内多表进行数据操作时，针对表做排序，按照最优排序
	Alter(s global.TableActiveInput) (any, error)
	CreateDatabase(s global.TableActiveInput) (any, error)
	Create(s global.TableActiveInput) (any, error)
	Drop(s global.TableActiveInput) (any, error)
	Recover(s global.TableActiveInput) (any, error)
}
